package com.example.sup.aspect;

import com.example.sup.aspect.annotation.CheckLogin;
import com.example.sup.entity.UserInfo;
import com.example.sup.exception.UnLoginException;
import com.example.sup.utils.ApplicationContextUtil;
import com.example.sup.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

import static com.example.sup.constants.SupConstants.TOKEN_PREFIX;

/**
 * @ClassName CheckLoginAspect
 * @Description {TODO}
 * @Author 李哲
 * @Date 11:39 2024/8/1
 * @Version 1.0
 */
@Aspect
@Component
@Slf4j
@Order(10)
public class CheckLoginAspect {
    /**
     * 根据token获取用户信息，将用户信息注入到方法参数
     * @param joinPoint   连接点(spring 中连接点可以认为就是指的方法)
     * @param clk
     */
    @Around("@annotation(clk)")
    public Object checkLoginBefore(ProceedingJoinPoint joinPoint, CheckLogin clk) throws Throwable {
        RedisUtils redisUtils = ApplicationContextUtil.<RedisUtils>getBean("redisUtils", RedisUtils.class);
        //TODO 1.获取request山下文获取request对象
        HttpServletRequest request = ((ServletRequestAttributes)(RequestContextHolder.getRequestAttributes())).getRequest();
        String token = request.getHeader("token");
        List<UserInfo> userInfoList = redisUtils.get(TOKEN_PREFIX+token,UserInfo.class);
        if(userInfoList==null||userInfoList.size()<=0){
            throw new UnLoginException("未登录，请先登录");
        }
        //TODO 1.prison表--查询登录用户所关联的监视列表
        UserInfo userInfo = userInfoList.get(0);
        //TODO 2.将 用户信息绑定到controller的参数
        Object[] methodParam = joinPoint.getArgs();
        methodParam[0]=userInfo;
        //TODO 3.调用目标方法同时传递修改的参数
        Object result = joinPoint.proceed(methodParam);
        return result;

    }
}
